
; Init8259A -----------------------------------------------------------------
Init8259A:
	mov	al, 011h
	out	020h, al		; 主8259, ICW1.
	call	io_delay

	out	0A0h, al		; 从8259, ICW1.
	call	io_delay

	mov	al, 020h		; IRQ0 对应中断向量 0x20
	out	021h, al		; 主8259, ICW2.
	call	io_delay

	mov	al, 028h		; IRQ8 对应中断向量 0x28
	out	0A1h, al		; 从8259, ICW2.
	call	io_delay

	mov	al, 004h		; IR2 对应从8259
	out	021h, al		; 主8259, ICW3.
	call	io_delay

	mov	al, 002h		; 对应主8259的 IR2
	out	0A1h, al		; 从8259, ICW3.
	call	io_delay

	mov	al, 001h
	out	021h, al		; 主8259, ICW4.
	call	io_delay

	out	0A1h, al		; 从8259, ICW4.
	call	io_delay

	mov	al, 11111111b	; 屏蔽主8259所有中断
	out	021h, al		; 主8259, OCW1.
	call	io_delay

	mov	al, 11111111b	; 屏蔽从8259所有中断
	out	0A1h, al		; 从8259, OCW1.
	call	io_delay

	ret
; Init8259A END--------------------------------------------------------------

; PIT -----------------------------------------------------------------------
InitPIT:; 初始化PIT，设置时钟周期为100HZ
	mov al, 34h
	out 43h, al
	
	mov al, 9ch
	out 40h, al
	
	mov al, 2eh
	out 40h, al
	
	ret
; PIT END--------------------------------------------------------------------

; open_handler --------------------------------------------------------------
open_handler:
	mov	al, 11111100b	; 仅仅开启键盘、定时器中断
	out	021h, al		; 主8259, OCW1.
	call	io_delay

	mov	al, 11111111b	; 屏蔽从8259所有中断
	out	0A1h, al		; 从8259, OCW1.
	call	io_delay

	ret
; open_handler END-----------------------------------------------------------

; io_delay ------------------------------------------------------------------
io_delay:
	nop
	nop
	nop
	nop
	ret
; io_delay END---------------------------------------------------------------

; int_handler ---------------------------------------------------------------

; clock_fun -----------------------------------------------------------------
CLOCKMSG_ADDR	equ	0x180000
PROCMSG_ADDR	equ 0x200000
PROCMSG_MEMBER	equ PROCMSG_ADDR + 2 * 4
PROC_STACK_SIZE equ 18

_ClockHandler:
ClockHandler	equ	_ClockHandler - $$

; 发送 EOI
.Send_EOI:
	mov	al, 20h
	out	20h, al
.Send_EOI_END:

; 设置计时变量
	mov al, [CLOCKMSG_ADDR]
	inc	al
	mov [CLOCKMSG_ADDR], al

; 判断是否改变进程
	xor ax, ax
	xor dx, dx
	mov al, [CLOCKMSG_ADDR]
	mov bx, 2
	div bx
	cmp dx, 0
	jne .CLOCK_EXIT

	mov ebx, [.PROC_CHAGE_NUM]
	cmp ebx, 1
	je .TO_PROC_2
	cmp ebx, 2
	je .TO_PROC_3
	cmp ebx, 3
	je .TO_PROC_4
	cmp ebx, 4
	je .BACK_PROC_0
	cmp ebx, 5
	je .BACK_PROC_1
	cmp ebx, 6
	je .BACK_PROC_2
	cmp ebx, 7
	je .BACK_PROC_3
	cmp ebx, 8
	je .BACK_PROC_4
	
.TO_PROC_1:
	mov eax, 1
	mov [.PROC_CHAGE_NUM], eax
	
	call PUSH_REGS_0
	mov eax, 1
	call GET_NEW_EIP
	jmp .CLOCK_EXIT
	
.TO_PROC_2:
	mov eax, 2
	mov [.PROC_CHAGE_NUM], eax
	
	mov eax, 1
	call PUSH_REGS_1
	mov eax, 2
	call GET_NEW_EIP
	jmp .CLOCK_EXIT
	
.TO_PROC_3:
	mov eax, 3
	mov [.PROC_CHAGE_NUM], eax
	
	mov eax, 2
	call PUSH_REGS_1
	mov eax, 3
	call GET_NEW_EIP
	jmp .CLOCK_EXIT

.TO_PROC_4:
	mov eax, 4
	mov [.PROC_CHAGE_NUM], eax
	
	mov eax, 3
	call PUSH_REGS_1
	mov eax, 4
	call GET_NEW_EIP
	jmp .CLOCK_EXIT

.BACK_PROC_0:
	mov eax, 5
	mov [.PROC_CHAGE_NUM], eax

	mov eax, 4
	call PUSH_REGS_1
	call POP_PRGS_0
	jmp .CLOCK_EXIT

.BACK_PROC_1:
	mov eax, 6
	mov [.PROC_CHAGE_NUM], eax

	call PUSH_REGS_0
	mov eax, 1
	call POP_PRGS_1
	jmp .CLOCK_EXIT

.BACK_PROC_2:
	mov eax, 7
	mov [.PROC_CHAGE_NUM], eax

	mov eax, 1
	call PUSH_REGS_1
	mov eax, 2
	call POP_PRGS_1
	jmp .CLOCK_EXIT

.BACK_PROC_3:
	mov eax, 8
	mov [.PROC_CHAGE_NUM], eax

	mov eax, 2
	call PUSH_REGS_1
	mov eax, 3
	call POP_PRGS_1
	jmp .CLOCK_EXIT

.BACK_PROC_4:
	mov eax, 4
	mov [.PROC_CHAGE_NUM], eax

	mov eax, 3
	call PUSH_REGS_1
	mov eax, 4
	call POP_PRGS_1
	jmp .CLOCK_EXIT

.CLOCK_EXIT:

	iretd

; 进程切换标号
.PROC_CHAGE_NUM:
	dd 0

%include "load_proc.asm"

; clock_fun END -------------------------------------------------------------

; keyboard_fun --------------------------------------------------------------
KEYBOARDMSG_ADDR	equ	0x190000
KEYBOARDBUFF_ADDR	equ	KEYBOARDMSG_ADDR	+ 10
KEYBOARDBUFF_PUSHIP	equ	KEYBOARDBUFF_ADDR
KEYBOARDBUFF_POPIP	equ	KEYBOARDBUFF_PUSHIP	+ 4
KEYBOARDBUFF_BUFF	equ	KEYBOARDBUFF_POPIP	+ 4

_KeyBoardHandler:
KeyBoardHandler	equ	_KeyBoardHandler - $$

	mov	edx, 20h			;.1	.1--.6 得到按键扫描码
	mov al,	61h				;.2
	out dx, al				;.3

	mov edx, 60h			;.4
	mov eax, 0				;.5
	in  al, dx				;.6

	mov	ah, 1
	mov	[KEYBOARDMSG_ADDR], ah
	mov	[KEYBOARDMSG_ADDR + 1], al
	
	;// 键盘码缓冲区入值
	;if(1 == keyboard_msg -> src_data[0] && keyboard_msg -> src_data[1] <= 128 )
	;{
	;	keyboard_buff -> buff[keyboard_buff -> push_ip] = keyboard_msg -> src_data[1];

	;	if(keyboard_buff -> push_ip < 32)
	;	{
	;		keyboard_buff -> push_ip ++;
	;	}
	;	else
	;	{
	;		keyboard_buff -> push_ip = 0;
	;	}

	;	keyboard_msg -> src_data[0] = 0;
	;}
	;//	键盘码缓冲区入值 END.
	
	;cmp byte [KEYBOARDMSG_ADDR], 1
	;jne .END_PSHU_VALUES
	cmp byte [KEYBOARDMSG_ADDR + 1], 128
	ja	.END_PSHU_VALUES

	mov eax, KEYBOARDBUFF_BUFF
	add eax, [KEYBOARDBUFF_PUSHIP]
	mov bl, [KEYBOARDMSG_ADDR + 1]
	mov [eax], bl

	cmp dword [KEYBOARDBUFF_PUSHIP], 32
	jae .1
	inc dword [KEYBOARDBUFF_PUSHIP]
	jmp .2
.1:
	mov dword [KEYBOARDBUFF_PUSHIP], 0
.2:
	mov byte [KEYBOARDMSG_ADDR], 0
.END_PSHU_VALUES:

	iretd

; keyboard_fun END ----------------------------------------------------------

; int_handler END------------------------------------------------------------
